package com.miyu.system.controller.file;

import cn.hutool.core.lang.Pair;
import com.miyu.system.service.file.FileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.liuxp.minioplus.api.model.dto.FileMetadataInfoDTO;
import org.liuxp.minioplus.api.model.vo.CompleteResultVo;
import org.liuxp.minioplus.api.model.vo.FileCheckResultVo;
import org.liuxp.minioplus.api.model.vo.FileMetadataInfoVo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件服务
 * 处理文件上传 下载 预览 删除等操作
 * @author longm
 * @date 2024/12/13
 */
@Slf4j
@RestController
@RequestMapping("fileService")
@RequiredArgsConstructor
public class FileController {
    private final FileService fileService;


    /**
     * 上传任务初始化
     * @param fileMd5 文件md5
     * @param fullFileName 文件名（含扩展名）
     * @param fileSize 文件长度
     * @param isPrivate 是否私有 false:否 true:是
     * @param userId  用户编号
     * @return {@link FileCheckResultVo}
     */
    @RequestMapping("init")
    FileCheckResultVo init(String fileMd5, String fullFileName, long fileSize, Boolean isPrivate, String userId){

        return fileService.init(fileMd5, fullFileName, fileSize, isPrivate, userId);
    }

    /**
     * 取得文件下载地址
     * @param fileMetadataInfo 文件KEY
     * @return 文件下载地址
     */
    @RequestMapping("download")
    String download(@RequestBody FileMetadataInfoDTO fileMetadataInfo){
        String fileKey =fileMetadataInfo.getFileKey();
        String userId = fileMetadataInfo.getCreateUser();
        return fileService.download(fileKey, userId);
    }

    /**
     * 创建文件 上传文件
     *
     * @param file 文件
     * @return {@link FileMetadataInfoVo }
     * @throws IOException io异常
     */
    @RequestMapping(value = "upLoadFile" )
   public List<FileMetadataInfoVo> createFile(@RequestParam(value = "file", required = false) MultipartFile[] file) throws IOException {
        List<FileMetadataInfoVo> files = new ArrayList<>();
        for (MultipartFile fileItem : file) {
            String fileName = fileItem.getOriginalFilename();
            files.add(fileService.createFile(fileName, false, "10001", fileItem.getInputStream()));
        }
        return files;
    }

    /**
     * 源文件列表
     *
     * @param fileMetadataInfo 文件元数据信息
     * @return {@link List }<{@link FileMetadataInfoVo }>
     */
    @RequestMapping("getFileList")
    List<FileMetadataInfoVo> list(@RequestBody FileMetadataInfoDTO fileMetadataInfo){
        List<FileMetadataInfoVo> list = new ArrayList<>();

        return fileService.list(fileMetadataInfo);
    }

    /**
     * 图片预览 获取预览地址
     *
     * @param fileMetadataInfo 文件元数据信息
     * @return {@link String }
     */
    @RequestMapping("preview")
   public  String preview(@RequestBody FileMetadataInfoDTO fileMetadataInfo){
        String fileKey =fileMetadataInfo.getFileKey();
        String userId = fileMetadataInfo.getCreateUser();
      return  fileService.preview(fileKey, userId);
    }

    /**
     * 图像获取地址
     *
     * @param fileMetadataInfo 文件元数据信息
     * @return {@link String }
     */
    @RequestMapping("image")
    public  String image(@RequestBody FileMetadataInfoDTO fileMetadataInfo){
        String fileKey =fileMetadataInfo.getFileKey();
        String userId = fileMetadataInfo.getCreateUser();
        return  fileService.image(fileKey, userId);
    }

    /**
     * 查询元数据信息
     * @param key 文件key
     * @return 文件元数据信息
     */
    @RequestMapping("one")
    public  FileMetadataInfoVo one(String key){
       return fileService.one(key);
    }

    /**
     * 合并已分块的文件
     * @param fileKey 文件关键
     * @param partMd5List 文件分块md5列表
     * @param userId  用户编号
     * @return {@link CompleteResultVo}
     */
    @RequestMapping("complete")
    public CompleteResultVo complete(String fileKey, List<String> partMd5List, String userId){
        return fileService.complete(fileKey, partMd5List, userId);
    }
    /**
     * 创建文件
     * 尽量不要用本方法处理大文件，大文件建议使用前端直传
     * @param fullFileName 文件名（含扩展名）
     * @param isPrivate 是否私有 false:否 true:是
     * @param userId  用户编号
     * @param fileBytes 文件字节流
     * @return 文件元数据信息
     */
    @RequestMapping("createFileByBate")
    public  FileMetadataInfoVo createFileByBate(String fullFileName, Boolean isPrivate, String userId, byte[] fileBytes){
        return fileService.createFile(fullFileName, isPrivate, userId, fileBytes);
    }

    /**
     * 创建文件
     * 尽量不要用本方法处理大文件，大文件建议使用前端直传
     * @param fullFileName 文件名（含扩展名）
     * @param isPrivate 是否私有 false:否 true:是
     * @param userId  用户编号
     * @param inputStream 文件输入字节流
     * @return 文件元数据信息
     */
    @RequestMapping("createFileByStream")
    public FileMetadataInfoVo createFileByStream(String fullFileName, Boolean isPrivate, String userId, InputStream inputStream){
        return fileService.createFile(fullFileName, isPrivate, userId, inputStream);
    }

    /**
     * 创建文件
     * 尽量不要用本方法处理大文件，大文件建议使用前端直传
     * @param fullFileName 文件名（含扩展名）
     * @param isPrivate 是否私有 false:否 true:是
     * @param userId  用户编号
     * @param url 文件地址
     * @return 文件元数据信息
     */
    @RequestMapping("createFileByUrl")
    public FileMetadataInfoVo createFileByUrl(String fullFileName, Boolean isPrivate, String userId, String url){
        return fileService.createFile(fullFileName, isPrivate, userId, url);
    }
    /**
     * 创建大文件
     * 大文件建议使用本方法
     * @param fullFileName 文件名（含扩展名）
     * @param md5 文件名MD5
     * @param fileSize 文件名大小
     * @param isPrivate 是否私有 false:否 true:是
     * @param userId  用户编号
     * @param inputStream 文件输入字节流
     * @return 文件元数据信息
     */
    @RequestMapping("createBigFile")
    public FileMetadataInfoVo createBigFile(String fullFileName, String md5, long fileSize,Boolean isPrivate, String userId, InputStream inputStream){
        return fileService.createBigFile(fullFileName, md5, fileSize, isPrivate, userId, inputStream);
    }

    /**
     * 根据文件key读取文件字节流
     * @param fileKey 文件key
     * @return 文件字节流
     */
    @RequestMapping("read")
    public Pair<FileMetadataInfoVo,byte[]> read(String fileKey){
        return fileService.read(fileKey);
    }
    /**
     * 根据文件key删除文件
     * @param fileKey 文件key
     * @return 是否成功
     */
    @RequestMapping("remove")
    public Boolean remove(String fileKey){
        return fileService.remove(fileKey);
    }

}
